﻿using System;

using System.Text.RegularExpressions;
using System.Threading;

namespace yeqw.FrameWork
{
    public class AsynchronousRegex
    {
        public static ResultInfo<MatchCollection> GetAsynRegexMatches(Regex regex,string Input)
        {
            AsynchronousRegex ar = new AsynchronousRegex(5000); //1000是设置1000为超时时限 

            MatchCollection mc=  ar.Matches(regex, Input);
            return new ResultInfo<MatchCollection>(ar.IsTimeout, mc);

        }
        public static ResultInfo<Match> GetAsynRegexMatch(Regex regex, string Input)
        {
            AsynchronousRegex ar = new AsynchronousRegex(5000); //1000是设置1000为超时时限 

            Match m = ar.Match(regex, Input);
            return new ResultInfo<Match>(ar.IsTimeout, m);

        }
        
        private MatchCollection mc;
        private Match m;
        private int _timeout;        // 最长休眠时间(超时),毫秒
        private int sleepCounter;
        private int sleepInterval;    // 休眠间隔,毫秒
        private bool _isTimeout;

        public bool IsTimeout
        {
            get { return this._isTimeout; }
        }

        public AsynchronousRegex(int timeout)
        {
            this._timeout = timeout;
            this.sleepCounter = 0;
            this.sleepInterval = 100;
            this._isTimeout = false;

            this.mc = null;
            this.m = null;
        }
        public Match Match(Regex regex, string input)
        {
            Reg r = new Reg(regex, input);
            r.OnMatchComplete += new Reg.MatchCompleteHandler(this.MatchCompleteHandler);

            Thread t = new Thread(new ThreadStart(r.Match));
            t.Start();

            this.Sleep(t);

            t = null;
            return m;
        }

        public MatchCollection Matches(Regex regex, string input)
        {
            Reg r = new Reg(regex, input);
            r.OnMatchesComplete += new Reg.MatchesCompleteHandler(this.MatchesCompleteHandler);

            Thread t = new Thread(new ThreadStart(r.Matches));
            t.Start();

            this.Sleep(t);

            t = null;
            return mc;
        }

        private void Sleep(Thread t)
        {
            if (t != null && t.IsAlive)
            {
                Thread.Sleep(TimeSpan.FromMilliseconds(this.sleepInterval));

                this.sleepCounter++;
                if (this.sleepCounter * this.sleepInterval >= this._timeout)
                {
                    t.Abort();
                    this._isTimeout = true;
                }
                else
                {
                    this.Sleep(t);
                }
            }
        }

        private void MatchesCompleteHandler(MatchCollection mc)
        {
            this.mc = mc;
        }
        private void MatchCompleteHandler(Match m)
        {
            this.m = m;
        }

        class Reg
        {
            internal delegate void MatchesCompleteHandler(MatchCollection mc);
            internal event MatchesCompleteHandler OnMatchesComplete;
            internal delegate void MatchCompleteHandler(Match m);
            internal event MatchCompleteHandler OnMatchComplete;
            public Reg(Regex regex, string input)
            {
                this._regex = regex;
                this._input = input;
            }

            private string _input;
            public string Input
            {
                get { return this._input; }
                set { this._input = value; }
            }

            private Regex _regex;
            public Regex Regex
            {
                get { return this._regex; }
                set { this._regex = value; }
            }

            internal void Match()
            {
                Match m = this._regex.Match(this._input); // 这里有可能造成cpu资源耗尽
                if (m != null)   
                {
                    this.OnMatchComplete(m);
                }
            }
            internal void Matches()
            {
                MatchCollection mc = this._regex.Matches(this._input);
                if (mc != null && mc.Count > 0)    // 这里有可能造成cpu资源耗尽
                {
                    this.OnMatchesComplete(mc);
                }
            }
        }
    }
}
